package scriptTool;

import com.itextpdf.html2pdf.ConverterProperties;
import com.itextpdf.html2pdf.HtmlConverter;
import com.itextpdf.html2pdf.resolver.font.DefaultFontProvider;
import com.itextpdf.kernel.geom.PageSize;
import com.itextpdf.layout.font.FontProvider;
import com.itextpdf.styledxmlparser.css.media.MediaDeviceDescription;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;

import java.io.File;
import java.io.FileOutputStream;


/**
 * html 文件 代码转 pdf 文件
 *
 * 需要的依赖：
 *         <dependency>
 *             <groupId>org.jsoup</groupId>
 *             <artifactId>jsoup</artifactId>
 *             <version>1.15.4</version>
 *         </dependency>
 *         <dependency>
 *             <groupId>com.itextpdf</groupId>
 *             <artifactId>html2pdf</artifactId>
 *             <version>3.0.5</version>
 *         </dependency>
 */
public class HtmlChangePDF {

    public static void main(String[] args) {
        String htmlInputFilePath = "src/main/java/scriptTool/index.html";
        String pdfOutputPath = "src/main/java/scriptTool/index.pdf";
        String fontPath = "src/main/java/scriptTool/Regular.ttf";

        try {
            // 读取 HTML 文件内容
            File inputHtml = new File(htmlInputFilePath);
            Document doc = Jsoup.parse(inputHtml, "UTF-8");

            // 处理图片分页
            handleImagePagination(doc);

            String htmlContent = doc.outerHtml();

            // 创建转换器属性
            ConverterProperties converterProperties = new ConverterProperties();

            // 设置字体
            FontProvider fontProvider = new DefaultFontProvider(false, false, false);
            fontProvider.addFont(fontPath);
            converterProperties.setFontProvider(fontProvider);

            // 设置基础URI，用于解析相对路径的图片
            String baseUri = new File(htmlInputFilePath).getParent();
            converterProperties.setBaseUri(baseUri);

            // 设置媒体设备描述
            MediaDeviceDescription mediaDeviceDescription = new MediaDeviceDescription("screen");
            mediaDeviceDescription.setWidth(PageSize.A4.getWidth());
            converterProperties.setMediaDeviceDescription(mediaDeviceDescription);

            // 在转换之前添加图片预加载检查
            preloadImages(doc);

            // 将 HTML 内容转换为 PDF
            try (FileOutputStream outputStream = new FileOutputStream(pdfOutputPath)) {
                // 确保输出目录存在
                new File(pdfOutputPath).getParentFile().mkdirs();

                HtmlConverter.convertToPdf(
                        htmlContent,
                        outputStream,
                        converterProperties
                );
            }

            System.out.println("PDF saved to " + pdfOutputPath);

        } catch (Exception e) {
            System.err.println("Error converting HTML to PDF: " + e.getMessage());
            e.printStackTrace();
        }
    }

    // 处理图片分页
    private static void handleImagePagination(Document doc) {
        addBaseStyles(doc);

        doc.select("img").forEach(img -> {
            // 获取原始样式
            String originalStyle = img.attr("style");

            // 创建包装容器
            Element wrapper = doc.createElement("div");
            wrapper.attr("class", "image-wrapper");

            // 将图片包装在容器中
            img.before(wrapper);
            wrapper.appendChild(img);

            // 合并样式
            StringBuilder styleBuilder = new StringBuilder();
            if (!originalStyle.isEmpty()) {
                styleBuilder.append(originalStyle).append("; ");
            }
            styleBuilder.append("max-width: 100%; height: auto;");
            img.attr("style", styleBuilder.toString());
        });
    }

    // 添加基础样式
    private static void addBaseStyles(Document doc) {
        Element head = doc.head();
        if (head == null) {
            head = doc.createElement("head");
            doc.prependChild(head);
        }

        Element style = doc.createElement("style");
        style.text(
                "@page { size: A4 portrait; margin: 1cm; }" +
                        "body { margin: 0; padding: 0; }" +
                        ".image-wrapper {" +
                        "    page-break-inside: avoid;" +
                        "    page-break-before: auto;" +
                        "    page-break-after: auto;" +
                        "    margin: 1cm 0;" +
                        "    display: block;" +
                        "    width: 100%;" +
                        "    text-align: center;" +
                        "}" +
                        "img {" +
                        "    display: inline-block;" +
                        "    max-width: 100%;" +
                        "    height: auto;" +
                        "    object-fit: contain;" +
                        "}"
        );
        head.appendChild(style);
    }

    // 在转换之前添加图片预加载检查
    private static void preloadImages(Document doc) {
        doc.select("img").forEach(img -> {
            String src = img.attr("src");
            try {
                if (src.startsWith("http")) {
                    java.net.URL url = new java.net.URL(src);
                    java.net.URLConnection conn = url.openConnection();
                    conn.setConnectTimeout(5000);
                    conn.setReadTimeout(5000);
                    conn.connect();
                } else if (!src.startsWith("data:")) {
                    // 检查本地文件是否存在
                    File imageFile = new File(src);
                    if (!imageFile.exists()) {
                        System.err.println("Warning: Local image not found: " + src);
                    }
                }
            } catch (Exception e) {
                System.err.println("Failed to preload image: " + src);
                e.printStackTrace();
            }
        });
    }

}
